package com.it.web.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.it.common.domain.dos.ArticleDO;
import com.it.common.domain.dos.ArticleTagRelDO;
import com.it.common.domain.dos.TagDO;
import com.it.common.enums.ResponseCodeEnum;
import com.it.common.exception.BizException;
import com.it.common.mapper.ArticleMapper;
import com.it.common.mapper.ArticleTagRelMapper;
import com.it.common.mapper.TagMapper;
import com.it.common.utils.PageResponse;
import com.it.common.utils.Response;
import com.it.web.convert.ArticleConvert;
import com.it.web.model.dto.tag.FindTagArticlePageListDto;
import com.it.web.model.dto.tag.FindTagListDto;
import com.it.web.model.vo.tag.FindTagArticlePageListRspVO;
import com.it.web.model.vo.tag.FindTagListRspVO;
import com.it.web.service.TagService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TagServiceImpl extends ServiceImpl<TagMapper, TagDO> implements TagService {


    @Resource
    private TagMapper tagMapper;

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private ArticleTagRelMapper articleTagRelMapper;

    @Override
    public Response findTagList(FindTagListDto findTagListDto) {

        Long size = findTagListDto.getSize();

        List<TagDO> list = new ArrayList<>();
        if(Objects.isNull(size)){
            list =  tagMapper.findAll();
        }else{
            list = tagMapper.selectByLimit(size);
        }

        List<FindTagListRspVO> vos = new ArrayList<>();
        if(list!=null&&list.size()>0){
            vos = list.stream().map(tagDO -> FindTagListRspVO.builder().id(tagDO.getId())
                    .articlesTotal(tagDO.getArticlesTotal()).name(tagDO.getName()).build()).collect(Collectors.toList());
        }
        return Response.success(vos);
    }

    @Override
    public Response findTagPageList(FindTagArticlePageListDto findTagArticlePageListDto) {
        // 标签 ID
        Long tagId = findTagArticlePageListDto.getId();
        Long size = findTagArticlePageListDto.getSize();
        Long current = findTagArticlePageListDto.getCurrent();

        // 判断该标签是否存在
        TagDO tagDO = tagMapper.selectById(tagId);
        if(Objects.isNull(tagDO)){
            log.warn("==> 该标签不存在, tagId: {}", tagId);
            throw new BizException(ResponseCodeEnum.TAG_NOT_EXIST);
        }
        // 先查询该标签下所有关联的文章 ID
        List<ArticleTagRelDO> articleTagRelDOS = articleTagRelMapper.selectByTagId(tagId);
        // 若该标签下未发布任何文章
        if(CollectionUtils.isEmpty(articleTagRelDOS)){
            log.info("==> 该标签下还未发布任何文章, tagId: {}", tagId);
            return PageResponse.success(null, null);
        }
        // 提取所有文章 ID
        List<Long> articleIds = articleTagRelDOS.stream().map(ArticleTagRelDO::getArticleId).collect(Collectors.toList());
        // 根据文章 ID 集合查询文章分页数据
        Page<ArticleDO> page = articleMapper.selectPageListByArticleIds(current,size,articleIds);
        List<ArticleDO> articleDOS = page.getRecords();
        // DO 转 VO
        List<FindTagArticlePageListRspVO> vos = null;
        if(!CollectionUtils.isEmpty(articleDOS)){
            vos = articleDOS.stream().map(articleDO -> ArticleConvert.INSTANCE.convertDO2TagArticleVO(articleDO)).collect(Collectors.toList());
        }
        return PageResponse.success(page, vos);
    }
}
